package main

import (
	"context"
	"fmt"
	"github.com/jinzhu/gorm"
	"google.golang.org/grpc"
	anypb "google.golang.org/protobuf/types/known/anypb"
	"net"
	database "ticket-system/db"
	"ticket-system/ticket/pb"
)

type Server struct {
	proto.UnimplementedTicketGRPCServer
}

func (s *Server) SayHi(ctx context.Context, req *proto.Req) (res *proto.Res, err error) {
	fmt.Println(req.GetMessage())
	return &proto.Res{Message: "我是从Ticket服务端返回的grpc的内容"}, nil
}

func (s *Server) CreateDataAndDoc(ctx context.Context, req *proto.DataAndDocReq) (res *proto.DataAndDocRes, err error) {
	db, err := gorm.Open("mysql", "root:root1234@tcp(127.0.0.1:3306)/ticket?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()
	// 插入资料工单
	d := database.DataManage{
		CaseId:      int(req.CaseId),
		Amount:      int(req.Amount), // 默认值
		UpdateCount: 1,
	}
	create := db.Create(&d)
	// 插入文书工单
	d2 := database.DocGen{
		CaseId:      int(req.CaseId),
		Amount:      int(req.Amount), // 默认值
		UpdateCount: 1,
	}
	create2 := db.Create(&d2)
	flag := create.RowsAffected > 0 && create2.RowsAffected > 0
	return &proto.DataAndDocRes{IsSuccess: flag}, nil
}

func (s *Server) UpdateDataAndDoc(ctx context.Context, req *proto.DataAndDocReq) (res *proto.DataAndDocRes, err error) {
	db, err := gorm.Open("mysql", "root:root1234@tcp(127.0.0.1:3306)/ticket?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	// 更新资料工单
	flag := false
	if req.Type == 1 {
		// 查询该案件下的最后一笔订单
		// 获取按创建时间最新的记录
		var latestRecord database.DataManage
		db.Where("case_id = ?", req.CaseId).Order("created_at desc").First(&latestRecord)
		// 拿到UpdateCount
		cnt := latestRecord.UpdateCount
		if cnt == 10 {
			// 如果UpdateCount == 10 更新失败
			flag = false
		} else {
			// 否则插入一条新的记录
			d := database.DataManage{
				CaseId:      int(latestRecord.CaseId),
				Amount:      int(latestRecord.Amount), // 默认值
				UpdateCount: cnt + 1,
				Status:      latestRecord.Status,
			}
			create := db.Create(&d)
			flag = create.RowsAffected > 0
		}

	} else if req.Type == 2 {
		// 更新文书工单
		// 逻辑同上
	}

	return &proto.DataAndDocRes{IsSuccess: flag}, nil
}

func (s *Server) FinishDataAndDoc(ctx context.Context, req *proto.FinishDataAndDocReq) (res *proto.DataAndDocRes, err error) {
	db, err := gorm.Open("mysql", "root:root1234@tcp(127.0.0.1:3306)/ticket?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	// 更新资料工单
	flag := false
	if req.Type == 1 {
		// 更新工单的状态
		update := db.Model(&database.DataManage{}).Where("id = ?", req.TicketId).Updates(map[string]interface{}{"status": 88})
		flag = update.RowsAffected > 0
	} else if req.Type == 2 {
		// 更新文书工单
		// 逻辑同上
	}

	return &proto.DataAndDocRes{IsSuccess: flag}, nil
}

func (s *Server) GetAllTicket(ctx context.Context, req *proto.DataAndDocReq) (res *proto.GetAllTicketRes, err error) {
	db, err := gorm.Open("mysql", "root:root1234@tcp(127.0.0.1:3306)/ticket?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic("failed to connect database")
	}
	defer db.Close()

	var its []*anypb.Any
	// 查询该案件下的资料管理工单
	var dataManage []proto.DataManage
	db.Where("case_id = ?", req.CaseId).Find(&dataManage)
	for _, c := range dataManage {
		toAny, _ := serializeToAny(c)
		its = append(
			its,
			toAny,
		)
	}
	// 查询该案件下的文书生成工单
	var docGen []proto.DocGen
	db.Where("case_id = ?", req.CaseId).Find(&docGen)
	for _, c := range docGen {
		toAny, _ := serializeToAny2(c)
		its = append(
			its,
			toAny,
		)
	}
	// 返回结果
	return &proto.GetAllTicketRes{Items: its}, nil
}

func serializeToAny(message proto.DataManage) (*anypb.Any, error) {
	anyMsg, err := anypb.New(&message)
	if err != nil {
		return nil, err
	}
	return anyMsg, nil
}

func serializeToAny2(message proto.DocGen) (*anypb.Any, error) {
	anyMsg, err := anypb.New(&message)
	if err != nil {
		return nil, err
	}
	return anyMsg, nil
}

func main() {
	l, e := net.Listen("tcp", ":8889")
	if e != nil {
		return
	}
	ss := grpc.NewServer()
	proto.RegisterTicketGRPCServer(ss, &Server{})
	fmt.Println("工单服务监听在8889端口...")
	ss.Serve(l)
}
